﻿using System.Collections.Generic;

namespace CommandTools
{
    /*
     * 标准命令模板：[command_name] -[option1] -[option2] ... [argue1] [argue2] ... 
     * 示例：reg -i dxm 3 18823
     */
    /// <summary>
    /// 命令解析器
    /// </summary>
    public class CommandInterpreter
    {
        /// <summary>
        /// 默认构造函数
        /// </summary>
        public CommandInterpreter()
        {

        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="cmdText">命令文本</param>
        public CommandInterpreter(string cmdText)
        {
            if (string.IsNullOrEmpty(cmdText) || string.IsNullOrWhiteSpace(cmdText))
                return;
            SplitString(cmdText);
            Parse();
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="cmdText">命令文本</param>
        public CommandInterpreter(string[] cmdText)
        {
            StringList.Clear();
            for (int i = 0; i < cmdText.Length; i++)
            {
                cmdText[i] = cmdText[i].Trim();
                if (!string.IsNullOrEmpty(cmdText[i]))
                    StringList.Add(cmdText[i]);
            }
            Parse();
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="cmdText">命令文本</param>
        /// <param name="argsOnly">指示此对象中是否仅包含参数列表而不包含命令</param>
        public CommandInterpreter(string cmdText, bool argsOnly)
        {
            ArgsOnly = argsOnly;
            if (string.IsNullOrEmpty(cmdText) || string.IsNullOrWhiteSpace(cmdText))
                return;
            SplitString(cmdText);
            Parse();
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="cmdText">命令文本</param>
        /// <param name="argsOnly">指示此对象中是否仅包含参数列表而不包含命令</param>
        /// <param name="splitChar">解析命令时分割元素的依据</param>
        public CommandInterpreter(string cmdText, bool argsOnly, char splitChar)
        {
            SplitChar = splitChar;
            ArgsOnly = argsOnly;
            if (string.IsNullOrEmpty(cmdText) || string.IsNullOrWhiteSpace(cmdText))
                return;
            SplitString(cmdText);
            Parse();
        }


        /// <summary>
        /// 命令的名称
        /// </summary>
        public string Operation
        {
            get
            {
                if (ArgsOnly || StringList.Count < 1)
                    return null;
                else
                    return StringList[0];
            }
        }

        /// <summary>
        /// 命令的参数列表
        /// </summary>
        public string[] Argues
        {
            get
            {
                if (IsEmpty)
                    return NullArgsValue;
                if (ArgsOnly)
                    return StringList.GetRange(0, StringList.Count).ToArray();
                return (ArgsStartPos > 0 && ArgsStartPos < StringList.Count) ? StringList.GetRange(ArgsStartPos, StringList.Count - ArgsStartPos).ToArray() : NullArgsValue;
            }
        }

        /// <summary>
        /// 命令参数列表的字符串表示
        /// </summary>
        public string ArguesString
        {
            get
            {
                string temp = string.Empty;
                string[] tempArgues = Argues;
                for (int i = 0; i < tempArgues.Length; i++)
                    temp += tempArgues[i] + " ";
                return temp.Trim();
            }
        }

        /// <summary>
        /// 命令的可选项
        /// </summary>
        public string[] Options
        {
            get
            {
                if (IsEmpty || ArgsOnly)
                    return NullOpsValue;
                if (ArgsStartPos < 0)
                    return NullOpsValue;
                else
                {
                    string[] temp = StringList.GetRange(1, ArgsStartPos - 1).ToArray();
                    for (int i = 0; i < temp.Length; i++)
                        temp[i] = temp[i].TrimStart('-');
                    return temp;
                }
            }
        }


        /// <summary>
        /// 代表空参数的值
        /// </summary>
        public static string[] NullArgsValue => new string[0];

        /// <summary>
        /// 代表空可选项的值
        /// </summary>
        public static string[] NullOpsValue => new string[0];


        private int ArgsStartPos = -1;

        private List<string> StringList { get; } = new List<string>();

        /// <summary>
        /// 解析命令时的分割符
        /// </summary>
        public char SplitChar { get; set; } = ' ';

        /// <summary>
        /// 指示此对象中是否仅包含参数列表而不包含命令
        /// </summary>
        public bool ArgsOnly { get; set; } = false;

        /// <summary>
        /// 指示此命令是否为空
        /// </summary>
        public bool IsEmpty => StringList.Count == 0;


        /// <summary>
        /// 分割指令
        /// </summary>
        /// <param name="cmdText"></param>
        private void SplitString(string cmdText)
        {
            StringList.Clear();
            cmdText = cmdText.Trim();
            List<string> temp = new List<string>(cmdText.Split(SplitChar));
            for (int i = 0; i < temp.Count; i++)
            {
                temp[i] = temp[i].Trim();
                if (!string.IsNullOrEmpty(temp[i]))
                    StringList.Add(temp[i]);
            }
        }

        /// <summary>
        /// 解析指令
        /// </summary>
        /// <param name="cmdText">命令文本</param>
        private void Parse()
        {
            if (!ArgsOnly)
            {
                StringList[0] = StringList[0].ToLower();
                if (StringList.Count > 1)
                {
                    int i;
                    for (i = 1; i < StringList.Count; i++)
                    {
                        if (StringList[i][0] != '-')
                            break;
                    }
                    ArgsStartPos = i;
                }
            }
        }

        /// <summary>
        ///  返回表示当前对象的字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            string temp = "{ Operation=" + Operation + ", Argues=";
            foreach (var item in Argues)
                temp += item + ", ";
            temp += "}";
            return temp;
        }

    }

    ///*
    // * 标准可选项模板: -[option] | [arg1], [arg2] ... 
    // * 示例：-i|name, type
    // */
    ///// <summary>
    ///// 命令可选项类
    ///// </summary>
    //public class CommandOption
    //{
    //    public CommandOption()
    //    { }
    //    public CommandOption(string optionText)
    //    {
    //        OptionName = optionText;
    //    }
    //    public static CommandOption[] ConvertToCommandOptionArray(string[] ops)
    //    {
    //        if (ops == null)
    //            return null;
    //        CommandOption[] temp = new CommandOption[ops.Length];
    //        for (int i = 0; i < ops.Length; i++)
    //            temp[i] = new CommandOption(ops[i]);
    //        return temp;
    //    }
    //    public static CommandOption[] ConvertToCommandOptionArray(List<string> ops)
    //    {
    //        if (ops == null)
    //            return null;
    //        CommandOption[] temp = new CommandOption[ops.Count];
    //        for (int i = 0; i < ops.Count; i++)
    //            temp[i] = new CommandOption(ops[i]);
    //        return temp;
    //    }
    //    public string OptionName { get; private set; } = string.Empty;
    //}
}
